﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace IM.Easy.Core.Configuration
{
    public class ConfigManager : IConfigManager
    {
        private IHostApplicationBuilder host;

        private static IConfiguration _configuration;

        private static IHostEnvironment _env;


        //private static readonly Lazy<ConfigManager> _instance = new(() => new ConfigManager(host));

        public static ConfigManager Instance;

        //public static ConfigManager Instance => _instance.Value;

        //public ConfigManager(IConfiguration configuration)
        //{
        //    _configuration = configuration;
        //}


        public ConfigManager(IHostApplicationBuilder host)
        {
            this.host = host;
            _configuration = host.Configuration;
            _env = host.Environment;
        }


        // 静态方法来初始化配置
        public static void Initialize(IHostApplicationBuilder host)
        {
            Instance = new ConfigManager(host);
            Configure(host.Configuration);
        }


        public static void Configure(IConfiguration configuration = default)
        {
            _configuration ??= configuration;
            var configFolderArray = configuration.GetSection("ConfigurationFolder").Get<string[]>();
            var configFolder = configFolderArray?.FirstOrDefault();

            if (string.IsNullOrEmpty(configFolder))
            {
                throw new InvalidOperationException("文件目录未指定");
            }

            if (!Directory.Exists(configFolder))
            {
                throw new DirectoryNotFoundException($"文件目录 {configFolder} 不存在");
            }

            // 获取普通 JSON 文件
            var jsonFiles = Directory.GetFiles(configFolder, "*.json");

            // 获取环境相关的 JSON 文件
            var envFiles = Directory.GetFiles(configFolder, $"*.{_env.EnvironmentName}.json");

            // 合并去重
            var configFiles = jsonFiles
                .Concat(envFiles)
                .Distinct()
                .OrderBy(file => file.EndsWith($".{_env.EnvironmentName}.json", StringComparison.OrdinalIgnoreCase) ? 1 : 0) // 环境文件优先级高
                .ToArray();

            foreach (var file in configFiles)
            {
                var config = new ConfigurationBuilder()
                    .AddJsonFile(file, optional: true, reloadOnChange: true)
                    .Build();

                foreach (var kvp in config.AsEnumerable())
                {
                    configuration[kvp.Key] = kvp.Value;
                }
            }
        }

        public string GetConfigurationValue(string key)
        {
            return _configuration[key];
        }

        public T Get<T>() where T : IConfigurable, new()
        {
            // 获取 T 的类型
            var type = typeof(T);

            // 检查是否有自定义的 SectionNameAttribute 特性
            var sectionNameAttribute = type.GetCustomAttribute<SectionNameAttribute>();
            string sectionName;

            if (sectionNameAttribute != null)
            {
                // 使用特性中的 sectionName
                sectionName = sectionNameAttribute.Name;
            }
            else
            {
                // 如果没有特性，用类名作为 sectionName 并移除后缀 "Options"
                sectionName = type.Name.EndsWith("Options")
                    ? type.Name[..^"Options".Length]
                    : type.Name;
            }

            // 获取配置节
            var section = _configuration.GetSection(sectionName);
            if (!section.Exists())
            {
                return new T();
            }

            // 返回配置的对象
            return section.Get<T>();
        }

        public T GetSection<T>(string sectionName) where T : new()
        {
            // 获取配置节
            var section = _configuration.GetSection(sectionName);
            if (!section.Exists())
            {
                return new T();
            }

            // 返回配置的对象
            return section.Get<T>()!;
        }
    }

}
